package com.zeyi.blog.social.gtiee;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.client.RestTemplate;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * @author 黎先森
 */
public class GiteeAuthFilter extends AbstractAuthenticationProcessingFilter {

    private static final String CLIENT_ID = "e18f2b57e73810dd56d5aeb7f941847c8f90c74cde9608be6a83932a39b43946";
    private static final String CLIENT_SECRET = "6b9e4fef426c0fe505115250595404a3978cf06138c7a7f7fbd309805b9a7139";
    private static final String REDIRECT_URI = "https://www.lesslesson.com/auth-redirect";
    private static final String TOKEN_URL = "https://gitee.com/oauth/token?grant_type=authorization_code&code=%s&client_id=%s&redirect_uri=%s&client_secret=%s";
    private static final String USER_INFO_URL = "https://gitee.com/api/v5/user?access_token=%s";
    private RestTemplate restTemplate;

    public GiteeAuthFilter(RestTemplate restTemplate) {
        super(new AntPathRequestMatcher("/auth/gitee", "GET"));
        this.restTemplate = restTemplate;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        //前端传来的code
        String code = request.getParameter("code");
        if (StringUtils.isBlank(code)) return null;
        //获取token
        HttpHeaders headers = new HttpHeaders();
        headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");

        HttpEntity<Map<String,Object>> httpEntity = new HttpEntity<>(null, headers);
        Map<String,Object> resultMap = restTemplate.postForObject(
                String.format(TOKEN_URL, code, CLIENT_ID, REDIRECT_URI, CLIENT_SECRET),
                httpEntity,
                Map.class
        );
        if (resultMap == null) return null;
        ObjectMapper objectMapper = new ObjectMapper();
        String accessToken = (String) resultMap.get("access_token");
        //获取用户信息
        HttpEntity<String> requestEntity = new HttpEntity<>(null, headers);
        ResponseEntity<String> responseEntity = restTemplate.exchange(String.format(USER_INFO_URL, accessToken), HttpMethod.GET, requestEntity, String.class);
        String userInfo = responseEntity.getBody();
        objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        GiteeUser giteeUser = objectMapper.readValue(userInfo, GiteeUser.class);
        GiteeAuthToken giteeAuthToken = new GiteeAuthToken(giteeUser);
        giteeAuthToken.setDetails(authenticationDetailsSource.buildDetails(request));
        return this.getAuthenticationManager().authenticate(giteeAuthToken);
    }
}
